home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 050 / turbtool.arc / CHAPTER6.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1985-04-01  |  16.5 KB  |  832 lines

  1. {$A-}
  2. PROGRAM CHAPTER6;
  3. {$I TOOLU.PAS}
  4. {$I FPRIMS.PAS}
  5.  
  6. var cmdptr:file;
  7. PROCEDURE EDIT;
  8. CONST
  9.   MAXLINES=1000;
  10.   DITTO=255;
  11.   CURLINE=PERIOD;
  12.   LASTLINE=DOLLAR;
  13.   SCAN=47;
  14.   BACKSCAN=92;
  15.   ACMD=97;
  16.   CCMD=99;
  17.   DCMD=100;
  18.   ECMD=101;
  19.   EQCMD=EQUALS;
  20.   FCMD=102;
  21.   GCMD=103;
  22.   ICMD=105;
  23.   MCMD=109;
  24.   PCMD=112;
  25.   QCMD=113;
  26.   RCMD=114;
  27.   SCMD=115;
  28.   WCMD=119;
  29.   XCMD=120;
  30.  
  31. TYPE
  32.   STCODE=(ENDDATA,ERR,OK);
  33.   BUFTYPE=RECORD
  34.     TXT:INTEGER;
  35.     MARK:BOOLEAN;
  36.   END;
  37.  
  38. VAR
  39.   EDITFID:FILE OF CHARACTER;
  40.   BUF:ARRAY[0..MAXLINES]OF BUFTYPE;
  41.   RECIN:INTEGER;
  42.   RECOUT:INTEGER;
  43.   LINE1,LINE2,NLINES,CURLN,LASTLN:INTEGER;
  44.   PAT,LIN,SAVEFILE:XSTRING;
  45.   CURSAVE,I:INTEGER;
  46.   STATUS:STCODE;
  47.   MORE:BOOLEAN;
  48.  
  49.  
  50.  
  51.  
  52.  
  53.  
  54.  
  55. PROCEDURE GETTXT(N:INTEGER;VAR S:XSTRING);
  56. VAR
  57.   ch:char;JUNK:BOOLEAN;I:INTEGER;
  58. BEGIN
  59.   IF(N=0) THEN
  60.     S[1]:=ENDSTR
  61.   ELSE BEGIN
  62.     i:=0;
  63.     SEEK(EDITFID,BUF[N].TXT);
  64.     repeat
  65.       i:=succ(i);
  66.       READ(EDITFID,s[i]);
  67.       RECIN:=RECIN+1;
  68.     until S[I]=ENDSTR;
  69.   END
  70. END;
  71.  
  72.  
  73. FUNCTION GETMARK(N:INTEGER):BOOLEAN;
  74. BEGIN
  75.   GETMARK:=BUF[N].MARK
  76. END;
  77.  
  78. PROCEDURE PUTMARK(N:INTEGER;M:BOOLEAN);
  79. BEGIN
  80.   BUF[N].MARK:=M
  81. END;
  82.  
  83. FUNCTION DOPRINT(N1,N2:INTEGER):STCODE;
  84. VAR
  85.   I:INTEGER;
  86.   LINE:XSTRING;
  87. BEGIN
  88.   IF(N1<=0)THEN
  89.     DOPRINT:=ERR
  90.   ELSE BEGIN
  91.     FOR I:=N1 TO N2 DO BEGIN
  92.       GETTXT(I,LINE);
  93.       PUTSTR(LINE,STDOUT)
  94.     END;
  95.     CURLN:=N2;
  96.     DOPRINT:=OK
  97.   END
  98. END;
  99.  
  100. FUNCTION DEFAULT(DEF1,DEF2:INTEGER;
  101.   VAR STATUS:STCODE):STCODE;
  102. BEGIN
  103.   IF(NLINES=0)THEN BEGIN
  104.     LINE1:=DEF1;
  105.     LINE2:=DEF2
  106.   END;
  107.   IF(LINE1 > LINE2)OR(LINE1 <=0)THEN
  108.     STATUS:=ERR
  109.   ELSE
  110.     STATUS:=OK;
  111.   DEFAULT:=STATUS
  112. END;
  113.  
  114. FUNCTION PREVLN(N:INTEGER):INTEGER;
  115. BEGIN
  116.   IF(N<=0)THEN
  117.     PREVLN:=LASTLN
  118.   ELSE
  119.     PREVLN:=N-1
  120. END;
  121.  
  122. FUNCTION NEXTLN(N:INTEGER):INTEGER;
  123. BEGIN
  124.   IF(N>=LASTLN)THEN
  125.     NEXTLN:=0
  126.   ELSE
  127.     NEXTLN:=N+1
  128. END;
  129.  
  130. FUNCTION PATSCAN(WAY:CHARACTER;VAR N:INTEGER):STCODE;
  131. VAR
  132.   DONE:BOOLEAN;
  133.   LINE:XSTRING;
  134. BEGIN
  135.   N:=CURLN;
  136.   PATSCAN:=ERR;
  137.   DONE:=FALSE;
  138.   REPEAT
  139.     IF(WAY=SCAN)THEN
  140.       N:=NEXTLN(N)
  141.     ELSE
  142.       N:=PREVLN(N);
  143.     GETTXT(N,LINE);
  144.     IF(MATCH(LINE,PAT))THEN BEGIN
  145.       PATSCAN:=OK;
  146.       DONE:=TRUE
  147.     END
  148.   UNTIL(N=CURLN)OR(DONE)
  149. END;
  150.  
  151. FUNCTION ESC(VAR S:XSTRING; VAR I:INTEGER):CHARACTER;
  152. BEGIN
  153.   IF(S[I]<>ESCAPE) THEN
  154.     ESC:=S[I]
  155.   ELSE IF (S[I+1]=ENDSTR) THEN
  156.     ESC:=ESCAPE
  157.   ELSE BEGIN
  158.     I:=I+1;
  159.     IF (S[I]=ORD('N')) THEN
  160.       ESC:=NEWLINE
  161.     ELSE IF (S[I]=ORD('T')) THEN
  162.       ESC:=TAB
  163.     ELSE
  164.       ESC:=S[I]
  165.     END
  166. END;
  167. FUNCTION OPTPAT(VAR LIN:XSTRING;VAR I:INTEGER):STCODE;
  168. BEGIN
  169.   IF(LIN[I]=ENDSTR)THEN
  170.     I:=0
  171.   ELSE IF(LIN[I+1]=ENDSTR)THEN
  172.     I:=0
  173.   ELSE IF(LIN[I+1]=LIN[I])THEN
  174.     I:=I+1
  175.   ELSE
  176.     I:=MAKEPAT(LIN,I+1,LIN[I],PAT);
  177.   IF(PAT[1]=ENDSTR)THEN
  178.     I:=0;
  179.   IF(I=0)THEN BEGIN
  180.     PAT[1]:=ENDSTR;
  181.     OPTPAT:=ERR
  182.   END
  183.   ELSE
  184.     OPTPAT:=OK
  185. END;
  186.  
  187. PROCEDURE SKIPBL(VAR S:XSTRING;VAR I:INTEGER);
  188. BEGIN
  189.   WHILE(S[I]=BLANK)OR(S[I]=TAB)DO
  190.     I:=I+1
  191. END;
  192.  
  193. FUNCTION GETNUM(VAR LIN:XSTRING;VAR I,NUM:INTEGER;
  194.   VAR STATUS:STCODE):STCODE;
  195. BEGIN
  196.   STATUS:=OK;
  197.   SKIPBL(LIN,I);
  198.   IF(ISDIGIT(LIN[I]))THEN BEGIN
  199.     NUM:=CTOI(LIN,I);
  200.       I:=I-1
  201.   END
  202.   ELSE IF(LIN[I]=CURLINE)THEN
  203.     NUM:=CURLN
  204.   ELSE IF(LIN[I]=LASTLINE)THEN
  205.     NUM:=LASTLN
  206.   ELSE IF(LIN[I]=SCAN)OR(LIN[I]=BACKSCAN)THEN BEGIN
  207.     IF(OPTPAT(LIN,I)=ERR)THEN
  208.       STATUS:=ERR
  209.     ELSE
  210.       STATUS:=PATSCAN(LIN[I],NUM)
  211.   END
  212.   ELSE
  213.     STATUS:=ENDDATA;
  214.   IF(STATUS=OK)THEN
  215.     I:=I+1;
  216.   GETNUM:=STATUS
  217. END;
  218.  
  219. FUNCTION GETONE(VAR LIN:XSTRING;VAR I,NUM:INTEGER;
  220.   VAR STATUS:STCODE):STCODE;
  221.   VAR
  222.     ISTART,MUL,PNUM:INTEGER;
  223.   BEGIN
  224.     ISTART:=I;
  225.     NUM:=0;
  226.     IF(GETNUM(LIN,I,NUM,STATUS)=OK)THEN
  227.       REPEAT
  228.         SKIPBL(LIN,I);
  229.         IF(LIN[I]<>PLUS)AND(LIN[I]<>MINUS)THEN
  230.           STATUS:=ENDDATA
  231.         ELSE BEGIN
  232.           IF(LIN[I]=PLUS)THEN
  233.             MUL:=+1
  234.           ELSE
  235.             MUL:=-1;
  236.           I:=I+1;
  237.           IF(GETNUM(LIN,I,PNUM,STATUS)=OK)THEN
  238.             NUM:=NUM+MUL*PNUM;
  239.           IF(STATUS=ENDDATA)THEN
  240.             STATUS:=ERR
  241.         END
  242.       UNTIL(STATUS<>OK);
  243.     IF(NUM<0)OR(NUM > LASTLN)THEN
  244.       STATUS:=ERR;
  245.     IF(STATUS<>ERR)THEN BEGIN
  246.       IF(I<=ISTART)THEN
  247.         STATUS:=ENDDATA
  248.       ELSE
  249.         STATUS:=OK
  250.     END;
  251.     GETONE:=STATUS
  252.   END;
  253.   
  254.         
  255. FUNCTION GETLIST(VAR LIN:XSTRING;VAR I:INTEGER;
  256.   VAR STATUS:STCODE):STCODE;
  257. VAR
  258.   NUM:INTEGER;
  259.   DONE:BOOLEAN;
  260. BEGIN
  261.   LINE2:=0;
  262.   NLINES:=0;
  263.   DONE:=(GETONE(LIN,I,NUM,STATUS)<>OK);
  264.   WHILE(NOT DONE)DO BEGIN
  265.     LINE1:=LINE2;
  266.     LINE2:=NUM;
  267.     NLINES:=NLINES+1;
  268.     IF(LIN[I]=SEMICOL)THEN
  269.       CURLN:=NUM;
  270.     IF(LIN[I]=COMMA)OR(LIN[I]=SEMICOL)THEN BEGIN
  271.       I:=I+1;
  272.       DONE:=(GETONE(LIN,I,NUM,STATUS)<>OK)
  273.     END
  274.     ELSE
  275.       DONE:=TRUE
  276.   END;
  277.   NLINES:=MIN(NLINES,2);
  278.   IF(NLINES=0)THEN
  279.     LINE2:=CURLN;
  280.   IF(NLINES<=1)THEN
  281.     LINE1:=LINE2;
  282.   IF(STATUS<>ERR)THEN
  283.     STATUS:=OK;
  284.   GETLIST:=STATUS
  285. END;
  286.  
  287. PROCEDURE REVERSE(N1,N2:INTEGER);
  288. VAR
  289.   TEMP:BUFTYPE;
  290. BEGIN
  291.   WHILE(N1<N2)DO BEGIN
  292.     TEMP:=BUF[N1];
  293.     BUF[N1]:=BUF[N2];
  294.     BUF[N2]:=TEMP;
  295.     N1:=N1+1;
  296.     N2:=N2-1
  297.   END
  298. END;
  299. PROCEDURE BLKMOVE(N1,N2,N3:INTEGER);
  300. BEGIN
  301.   IF(N3<N1-1)THEN BEGIN
  302.     REVERSE(N3+1,N1-1);
  303.     REVERSE(N1,N2);
  304.     REVERSE(N3+1,N2)
  305.   END
  306.   ELSE IF(N3>N2)THEN BEGIN
  307.     REVERSE(N1,N2);
  308.     REVERSE(N2+1,N3);
  309.     REVERSE(N1,N3)
  310.   END
  311. END;
  312.  
  313. FUNCTION MOVE(LINE3:INTEGER):STCODE;
  314. BEGIN
  315.   IF(LINE1<=0)OR((LINE3>=LINE1)AND(LINE3<LINE2))THEN
  316.     MOVE:=ERR
  317.   ELSE BEGIN
  318.     BLKMOVE(LINE1,LINE2,LINE3);
  319.     IF(LINE3>LINE1)THEN
  320.       CURLN:=LINE3
  321.     ELSE
  322.        CURLN:=LINE3+(LINE2-LINE1+1);
  323.      MOVE:=OK
  324.    END
  325.  END;
  326.  
  327. FUNCTION LNDELETE(N1,N2:INTEGER;VAR STATUS:STCODE):
  328. STCODE;
  329. BEGIN
  330.   IF(N1<=0)THEN
  331.     STATUS:=ERR
  332.   ELSE BEGIN
  333.     BLKMOVE(N1,N2,LASTLN);
  334.     LASTLN:=LASTLN-(N2-N1+1);
  335.     CURLN:=PREVLN(N1);
  336.     STATUS:=OK
  337.   END;
  338.   LNDELETE:=STATUS
  339. END;
  340.  
  341. FUNCTION CKP(VAR LIN:XSTRING;I:INTEGER;
  342.   VAR PFLAG:BOOLEAN;VAR STATUS:STCODE):STCODE;
  343. BEGIN
  344.   SKIPBL(LIN,I);
  345.   IF(LIN[I]=PCMD)THEN BEGIN
  346.     I:=I+1;
  347.     PFLAG:=TRUE
  348.   END
  349.   ELSE
  350.     PFLAG:=FALSE;
  351.   IF(LIN[I]=NEWLINE)THEN
  352.     STATUS:=OK
  353.   ELSE
  354.     STATUS:=ERR;
  355.   CKP:=STATUS
  356. END;
  357.  
  358. FUNCTION PUTTXT(VAR LIN:XSTRING):STCODE;
  359. VAR I:INTEGER;
  360. BEGIN
  361.   PUTTXT:=ERR;
  362.   IF(LASTLN<MAXLINES) THEN BEGIN
  363.     i:=0;
  364.     seek(editfid,recout);
  365.     lastln:=lastln+1;
  366.     buf[lastln].txt:=recout;
  367.     repeat
  368.       i:=succ(i);
  369.       WRITE(EDITFID,lin[i]);
  370.       recout:=recout+1
  371.     until lin[i]=ENDSTR;
  372.     write(editfid,lin[i]);
  373.     PUTMARK(LASTLN,FALSE);
  374.     BLKMOVE(LASTLN,LASTLN,CURLN);
  375.     CURLN:=CURLN+1;
  376.     PUTTXT:=OK
  377.   END
  378. END;
  379.  
  380. PROCEDURE SETBUF;
  381. BEGIN
  382. (*$I-*)
  383.   ASSIGN(EDITFID,'EDTEMP');
  384.   RESET(EDITFID);
  385.   IF (IORESULT<>0) THEN REWRITE(EDITFID);
  386. (*$I+*)
  387.  
  388.   RECOUT:=0;
  389.   RECIN:=0;
  390.   CURLN:=0;
  391.   LASTLN:=0
  392. END;
  393.  
  394.  
  395. PROCEDURE CLRBUF;
  396. BEGIN
  397.   CLOSE(EDITFID);ERASE(EDITFID)
  398. END;
  399.  
  400. FUNCTION APPEND(LINE:INTEGER;GLOB:BOOLEAN):STCODE;
  401. VAR
  402.   EINLINE:XSTRING;
  403.   STAT:STCODE;
  404.   DONE:BOOLEAN;
  405. BEGIN
  406.   IF(GLOB)THEN
  407.     STAT:=ERR
  408.   ELSE BEGIN
  409.     CURLN:=LINE;
  410.     STAT:=OK;
  411.     DONE:=FALSE;
  412.     WHILE(NOT DONE)AND(STAT=OK)DO
  413.       IF(NOT GETLINE(EINLINE,STDIN,MAXSTR))THEN
  414.         STAT:=ENDDATA
  415.       ELSE IF(EINLINE[1]=PERIOD)
  416.         AND(EINLINE[2]=NEWLINE)THEN
  417.           DONE:=TRUE
  418.       ELSE IF(PUTTXT(EINLINE)=ERR)THEN
  419.         STAT:=ERR
  420.   END;
  421.   APPEND:=STAT
  422. END;
  423.  
  424. FUNCTION DOWRITE(N1,N2:INTEGER;VAR FIL:XSTRING):STCODE;
  425. VAR
  426.   I:INTEGER;
  427.   FD: FILEDESC;
  428.   LINE: XSTRING;
  429. BEGIN
  430.   FD:=CREATE(FIL,IOWRITE);
  431.   IF(FD=IOERROR)THEN
  432.     DOWRITE:=ERR
  433.   ELSE BEGIN
  434.     FOR I:=N1 TO N2 DO BEGIN
  435.       GETTXT(I,LINE);
  436.       PUTSTR(LINE,FD)
  437.     END;
  438.     XCLOSE(FD);
  439.     PUTDEC(N2-N1+1,1);
  440.     PUTC(NEWLINE);
  441.     DOWRITE:=OK
  442.   END
  443. END;
  444.  
  445. FUNCTION DOREAD(N:INTEGER;VAR FIL:XSTRING):STCODE;
  446. VAR
  447.   COUNT:INTEGER;
  448.   T:BOOLEAN;
  449.   STAT:STCODE;
  450.   FD:FILEDESC;
  451.   EINLINE:XSTRING;
  452. BEGIN
  453.   FD:=OPEN(FIL,IOREAD);
  454.   IF(FD=IOERROR)THEN
  455.     STAT:=ERR
  456.   ELSE BEGIN
  457.     CURLN:=N;
  458.     STAT:=OK;
  459.     COUNT:=0;
  460.     REPEAT
  461.       T:=GETLINE(EINLINE,FD,MAXSTR);
  462.       IF(T)THEN BEGIN
  463.         STAT:=PUTTXT(EINLINE);
  464.         IF(STAT<>ERR)THEN
  465.           COUNT:=COUNT+1
  466.       END
  467.     UNTIL(STAT<>OK)OR(T=FALSE);
  468.     XCLOSE(FD);
  469.     PUTDEC(COUNT,1);
  470.     PUTC(NEWLINE)
  471.   END;
  472.   DOREAD:=STAT
  473. END;
  474.  
  475. FUNCTION GETFN(VAR LIN:XSTRING;VAR I:INTEGER;
  476.   VAR FIL:XSTRING):STCODE;
  477. VAR
  478.   K:INTEGER;
  479.   STAT:STCODE;
  480.  
  481. FUNCTION GETWORD(VAR S:XSTRING;I:INTEGER;VAR OUT:
  482.   XSTRING):INTEGER;
  483. VAR
  484.   J:INTEGER;
  485. BEGIN
  486.   WHILE(S[I]IN [BLANK,TAB,NEWLINE])DO
  487.     I:=I+1;
  488.   J:=1;
  489.   WHILE(NOT(S[I]IN [ENDSTR,BLANK,TAB,
  490.     NEWLINE]))DO BEGIN
  491.     OUT[J]:=S[I];
  492.     I:=I+1;
  493.     J:=J+1
  494.   END;
  495.   OUT[J]:=ENDSTR;
  496.   IF(S[I]=ENDSTR)THEN
  497.     GETWORD:=0
  498.   ELSE
  499.     GETWORD:=I
  500. END;
  501.  
  502. BEGIN(*GETFN*)
  503.   STAT:=ERR;
  504.   IF(LIN[I+1]=BLANK)THEN BEGIN
  505.     K:=GETWORD(LIN,I+2,FIL);
  506.     IF(K>0)THEN
  507.       IF(LIN[K]=NEWLINE)THEN
  508.         STAT:=OK
  509.   END
  510.   ELSE IF(LIN[I+1]=NEWLINE)
  511.     AND(SAVEFILE[1]<>ENDSTR)THEN BEGIN
  512.       SCOPY(SAVEFILE,1,FIL,1);
  513.       STAT:=OK;
  514.   END;
  515.   IF(STAT=OK)AND(SAVEFILE[1]=ENDSTR)THEN
  516.     SCOPY(FIL,1,SAVEFILE,1);
  517.   GETFN:=STAT
  518. END;
  519.  
  520. PROCEDURE CATSUB(VAR LIN:XSTRING;S1,S2: INTEGER;
  521.   VAR SUB: XSTRING;VAR NEW:XSTRING;
  522.   VAR K:INTEGER;MAXNEW:INTEGER);
  523. VAR
  524.   I,J:INTEGER;
  525.   JUNK:BOOLEAN;
  526. BEGIN
  527.   I:=1;
  528.   WHILE(SUB[I]<>ENDSTR)DO BEGIN
  529.     IF(SUB[I]=DITTO)THEN
  530.       FOR J:=S1 TO S2-1 DO
  531.         JUNK:=ADDSTR(LIN[J],NEW,K,MAXNEW)
  532.       ELSE
  533.         JUNK:=ADDSTR(SUB[I],NEW,K,MAXNEW);
  534.       I:=I+1
  535.   END
  536. END;
  537.  
  538. FUNCTION SUBST( VAR SUB:XSTRING;GFLAG,GLOB:BOOLEAN):STCODE;
  539. VAR
  540.   NEW,OLD:XSTRING;
  541.   J,K,LASTM,LINE,M:INTEGER;
  542.   STAT:STCODE;
  543.   DONE,SUBBED,JUNK:BOOLEAN;
  544. BEGIN
  545.   IF(GLOB)THEN
  546.     STAT:=OK
  547.   ELSE
  548.     STAT:=ERR;
  549.     DONE:=(LINE1<=0);
  550.     LINE:=LINE1;
  551.     WHILE(NOT DONE)AND(LINE<=LINE2)DO BEGIN
  552.       J:=1;
  553.       SUBBED:=FALSE;
  554.       GETTXT(LINE,OLD);
  555.       LASTM:=0;
  556.       K:=1;
  557.       WHILE(OLD[K]<>ENDSTR)DO BEGIN
  558.         IF(GFLAG)OR(NOT SUBBED)THEN
  559.           M:=AMATCH(OLD,K,PAT,1)
  560.         ELSE
  561.           M:=0;
  562.         IF(M>0)AND(LASTM<>M)THEN BEGIN
  563.           SUBBED:=TRUE;
  564.           CATSUB(OLD,K,M,SUB,NEW,J,MAXSTR);
  565.           LASTM:=M
  566.         END;
  567.         IF(M=0)OR(M=K)THEN BEGIN
  568.           JUNK:=ADDSTR(OLD[K],NEW,J,MAXSTR);
  569.           K:=K+1
  570.         END
  571.         ELSE
  572.           K:=M
  573.       END;
  574.       IF(SUBBED)THEN BEGIN
  575.         IF(NOT ADDSTR(ENDSTR,NEW,J,MAXSTR))THEN BEGIN
  576.           STAT:=ERR;
  577.           DONE:=TRUE
  578.         END
  579.         ELSE BEGIN
  580.           STAT:=LNDELETE(LINE,LINE,STATUS);
  581.           STAT:=PUTTXT(NEW);
  582.           LINE2:=LINE2+CURLN-LINE;
  583.           LINE:=CURLN;
  584.           IF(STAT=ERR)THEN
  585.             DONE:=TRUE
  586.           ELSE
  587.             STAT:=OK
  588.           END
  589.         END;
  590.         LINE:=LINE+1
  591.       END;
  592.       SUBST:=STAT
  593.     END;
  594. FUNCTION MAKESUB(VAR ARG:XSTRING;FROM:INTEGER;
  595.   DELIM:CHARACTER;VAR SUB:XSTRING):INTEGER;
  596. VAR I,J:INTEGER;
  597.    JUNK:BOOLEAN;
  598. BEGIN
  599.   J:=1;
  600.   I:=FROM;
  601.   WHILE(ARG[I]<>DELIM)AND(ARG[I]<>ENDSTR)DO BEGIN
  602.     IF(ARG[I]=ORD('&'))THEN
  603.       JUNK:=ADDSTR(DITTO,SUB,J,MAXPAT)
  604.     ELSE
  605.       JUNK:=ADDSTR(ESC(ARG,I),SUB,J,MAXPAT);
  606.     I:=I+1
  607.   END;
  608.   IF(ARG[I]<>DELIM) THEN
  609.     MAKESUB:=0
  610.   ELSE IF (NOT ADDSTR(ENDSTR,SUB,J,MAXPAT))THEN
  611.     MAKESUB:=0
  612.   ELSE
  613.     MAKESUB:=I
  614. END;
  615. FUNCTION GETRHS(VAR LIN:XSTRING;VAR I:INTEGER;
  616.   VAR SUB:XSTRING;VAR GFLAG:BOOLEAN):STCODE;
  617. BEGIN
  618.   GETRHS:=OK;
  619.   IF(LIN[I]=ENDSTR)THEN
  620.     GETRHS:=ERR
  621.   ELSE IF(LIN[I+1]=ENDSTR)THEN
  622.     GETRHS:=ERR
  623.   ELSE BEGIN
  624.     I:=MAKESUB(LIN,I+1,LIN[I],SUB);
  625.     IF(I=0)THEN
  626.       GETRHS:=ERR
  627.     ELSE IF(LIN[I+1]=ORD('G'))THEN BEGIN
  628.       I:=I+1;
  629.       GFLAG:=TRUE
  630.     END
  631.     ELSE
  632.       GFLAG:=FALSE
  633.   END
  634. END;
  635.  
  636. FUNCTION DOCMD(VAR LIN:XSTRING;VAR I:INTEGER;
  637.   GLOB:BOOLEAN;VAR STATUS:STCODE):STCODE;
  638. VAR
  639.   FIL,SUB:XSTRING;
  640.   LINE3:INTEGER;
  641.   GFLAG,PFLAG:BOOLEAN;
  642. BEGIN
  643.   PFLAG:=FALSE;
  644.   STATUS:=ERR;
  645.   IF(LIN[I]=PCMD)THEN BEGIN
  646.     IF(LIN[I+1]=NEWLINE)THEN 
  647.       IF(DEFAULT(CURLN,CURLN,STATUS)=OK)THEN
  648.         STATUS:=DOPRINT(LINE1,LINE2)
  649.   END
  650.   ELSE IF(LIN[I]=NEWLINE)THEN BEGIN
  651.     IF(NLINES=0)THEN
  652.       LINE2:=NEXTLN(CURLN);
  653.     STATUS:=DOPRINT(LINE2,LINE2)
  654.   END
  655.   ELSE IF(LIN[I]=QCMD)THEN BEGIN
  656.     IF( LIN[I+1]=NEWLINE)AND(NLINES=0)AND(NOT GLOB)THEN
  657.   STATUS:=ENDDATA
  658.   END
  659.   ELSE IF(LIN[I]=ACMD)THEN BEGIN
  660.     IF(LIN[I+1]=NEWLINE)THEN
  661.       STATUS:=APPEND(LINE2,GLOB)
  662.   END
  663.   ELSE IF(LIN[I]=CCMD)THEN BEGIN
  664.     IF(LIN[I+1]=NEWLINE)THEN
  665.       IF(DEFAULT(CURLN,CURLN,STATUS)=OK)THEN
  666.       IF(LNDELETE(LINE1,LINE2,STATUS)=OK)THEN
  667.         STATUS:=APPEND(PREVLN(LINE1),GLOB)
  668.   END
  669.   ELSE IF(LIN[I]=DCMD)THEN BEGIN
  670.     IF(CKP(LIN,I+1,PFLAG,STATUS)=OK)THEN
  671.      IF(DEFAULT(CURLN,CURLN,STATUS)=OK)THEN
  672.      IF(LNDELETE(LINE1,LINE2,STATUS)=OK)THEN
  673.      IF(NEXTLN(CURLN)<>0)THEN
  674.        CURLN:=NEXTLN(CURLN)
  675.   END
  676.   ELSE IF(LIN[I]=ICMD)THEN BEGIN
  677.     IF(LIN[I+1]=NEWLINE)THEN BEGIN
  678.       IF(LINE2=0)THEN
  679.         STATUS:=APPEND(0,GLOB)
  680.       ELSE
  681.         STATUS:=APPEND(PREVLN(LINE2),GLOB)
  682.     END
  683.   END
  684.   ELSE IF(LIN[I]=EQCMD)THEN BEGIN
  685.     IF(CKP(LIN,I+1,PFLAG,STATUS)=OK)THEN BEGIN
  686.       PUTDEC(LINE2,1);
  687.       PUTC(NEWLINE)
  688.     END
  689.   END
  690.   ELSE IF(LIN[I]=MCMD)THEN BEGIN
  691.     I:=I+1;
  692.     IF(GETONE(LIN,I,LINE3,STATUS)=ENDDATA)THEN
  693.       STATUS:=ERR;
  694.     IF(STATUS =OK)THEN
  695.       IF(CKP(LIN,I,PFLAG,STATUS)=OK)THEN
  696.       IF(DEFAULT(CURLN,CURLN,STATUS)=OK)THEN
  697.         STATUS:=MOVE(LINE3)
  698.   END
  699.   ELSE IF(LIN[I]=SCMD)THEN BEGIN
  700.     I:=I+1;
  701.     IF(OPTPAT(LIN,I)=OK)THEN 
  702.     IF(GETRHS(LIN,I,SUB,GFLAG)=OK)THEN
  703.     IF(CKP(LIN,I+1,PFLAG,STATUS)=OK)THEN
  704.     IF(DEFAULT(CURLN,CURLN,STATUS)=OK)THEN
  705.       STATUS:=SUBST(SUB,GFLAG,GLOB)
  706.   END
  707.   ELSE IF(LIN[I]=ECMD)THEN BEGIN
  708.     IF(NLINES =0)THEN
  709.       IF(GETFN(LIN,I,FIL)=OK)THEN BEGIN
  710.         SCOPY(FIL,1,SAVEFILE,1);
  711.         CLRBUF;
  712.         SETBUF;
  713.         STATUS:=DOREAD(0,FIL)
  714.       END
  715.   END
  716.   ELSE IF(LIN[I]=FCMD)THEN BEGIN
  717.     IF(NLINES =0)THEN
  718.       IF(GETFN(LIN,I,FIL)=OK)THEN BEGIN
  719.         SCOPY(FIL,1,SAVEFILE,1);
  720.         PUTSTR(SAVEFILE,STDOUT);
  721.         PUTC(NEWLINE);
  722.         STATUS:=OK
  723.     END
  724.   END
  725.   ELSE IF(LIN[I]=RCMD)THEN BEGIN
  726.     IF(GETFN(LIN,I,FIL)=OK)THEN
  727.       STATUS:=DOREAD(LINE2,FIL)
  728.   END
  729.   ELSE IF(LIN[I]=WCMD)THEN BEGIN
  730.     IF(GETFN(LIN,I,FIL)=OK)THEN
  731.       IF(DEFAULT(1,LASTLN,STATUS)=OK)THEN
  732.         STATUS:=DOWRITE(LINE1,LINE2,FIL)
  733.   END;
  734.   IF(STATUS =OK)AND(PFLAG)THEN
  735.     STATUS:=DOPRINT(CURLN,CURLN);
  736.   DOCMD:=STATUS
  737. END;(*DOCMD*)
  738.  
  739. FUNCTION CKGLOB(VAR LIN: XSTRING;VAR I:INTEGER;
  740.   VAR STATUS:STCODE): STCODE;
  741. VAR
  742.   N:INTEGER;
  743.   GFLAG:BOOLEAN;
  744.   TEMP: XSTRING;
  745. BEGIN
  746.   IF(LIN[I]<>GCMD)AND(LIN[I]<>XCMD)THEN
  747.     STATUS:=ENDDATA
  748.   ELSE BEGIN
  749.     GFLAG:=(LIN[I]=GCMD);
  750.     I:=I+1;
  751.     IF(OPTPAT(LIN,I)=ERR)THEN
  752.       STATUS:=ERR
  753.     ELSE IF( DEFAULT(1,LASTLN,STATUS)<>ERR)THEN BEGIN
  754.       I:=I+1;
  755.       FOR N:=LINE1 TO LINE2 DO BEGIN
  756.         GETTXT(N,TEMP);
  757.         PUTMARK(N,(MATCH(TEMP,PAT)=GFLAG))
  758.       END;
  759.  
  760.       FOR N:=1 TO LINE1-1 DO
  761.         PUTMARK(N,FALSE);
  762.       FOR N:=LINE2+1 TO LASTLN DO
  763.         PUTMARK(N,FALSE);
  764.       STATUS:=OK
  765.     END
  766.   END;
  767.   CKGLOB:=STATUS
  768. END;
  769.  
  770. FUNCTION DOGLOB(VAR LIN:XSTRING;VAR I,CURSAVE:INTEGER;
  771.   VAR STATUS: STCODE):STCODE;
  772. VAR
  773.   COUNT,ISTART,N: INTEGER;
  774. BEGIN
  775.   STATUS:=OK;
  776.   COUNT:=0;
  777.   N:=LINE1;
  778.   ISTART:=I;
  779.   REPEAT
  780.     IF(GETMARK(N))THEN BEGIN
  781.       PUTMARK(N,FALSE);
  782.       CURLN:=N;
  783.       CURSAVE:=CURLN;
  784.       I:=ISTART;
  785.       IF(DOCMD(LIN,I,TRUE,STATUS)=OK)THEN
  786.         COUNT:=0
  787.     END
  788.     ELSE BEGIN
  789.       N:=NEXTLN(N);
  790.       COUNT:=COUNT + 1
  791.     END
  792.   UNTIL(COUNT > LASTLN)OR(STATUS <> OK);
  793.   DOGLOB:=STATUS
  794. END;
  795.  
  796. BEGIN
  797.   SETBUF;
  798.   PAT[1]:=ENDSTR;
  799.   SAVEFILE[1]:=ENDSTR;
  800.   IF(GETARG(2,SAVEFILE,MAXSTR))THEN
  801.     IF(DOREAD(0,SAVEFILE)=ERR)THEN
  802.       WRITELN('?');
  803.   MORE:=GETLINE(LIN,STDIN,MAXSTR);
  804.   WHILE(MORE)DO BEGIN
  805.     I:=1;
  806.     CURSAVE:=CURLN;
  807.     IF(GETLIST(LIN,I,STATUS)=OK)THEN BEGIN
  808.       IF(CKGLOB(LIN,I,STATUS)=OK)THEN
  809.         STATUS:=DOGLOB(LIN,I,CURSAVE,STATUS)
  810.       ELSE IF(STATUS<>ERR)THEN
  811.         STATUS:=DOCMD(LIN,I,FALSE,STATUS)
  812.     END;
  813.     IF(STATUS=ERR)THEN BEGIN
  814.       WRITELN('?');
  815.       CURLN:=MIN(CURSAVE,LASTLN)
  816.     END
  817.     ELSE IF(STATUS=ENDDATA)THEN
  818.       MORE:=FALSE;
  819.     IF(MORE)THEN
  820.       MORE:=GETLINE(LIN,STDIN,MAXSTR)
  821.   END;
  822.   CLRBUF
  823. END;
  824.  
  825. BEGIN
  826.   EDIT;
  827.   ENDCMD;assign(cmdptr,'SHELL.COM');execute(cmdptr)
  828. END.
  829.  
  830.  
  831.  
  832.